﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;

namespace ShareHelper
{
    /// <summary>
    ///保存界面配置 附加属性
    /// </summary>
    public partial class WPFConfiguration
    {
        /// <summary>
        ///获取附加属性值
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static bool GetIsRecord(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsRecordProperty);
        }

        /// <summary>
        ///设置附加属性值
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="value"></param>
        public static void SetIsRecord(DependencyObject obj, bool value)
        {
            obj.SetValue(IsRecordProperty, value);
        }

        /// <summary>
        ///附加属性 IsRecord
        /// </summary>
        public static readonly DependencyProperty IsRecordProperty =
            DependencyProperty.RegisterAttached("IsRecord", typeof(bool), typeof(WPFConfiguration), new PropertyMetadata(false));
    }

    /// <summary>
    /// 保存界面配置
    /// </summary>
    public static partial class WPFConfiguration
    {
        /// <summary>
        /// 配置保存路径 默认路径我的文档
        /// </summary>
        public static string Personal { get; set; } = Environment.GetFolderPath(Environment.SpecialFolder.Personal);

        #region 保存配置

        /// <summary>
        /// 保存窗口配置
        /// </summary>
        /// <param name="window">控件</param>
        /// <param name="name">文件名称</param>
        public static void Save(this ContentControl window, string name)
        {
            if (window.Content is Panel panel)
            {
                Save(panel, name);
            }
        }

        /// <summary>
        /// 保存窗口配置
        /// </summary>
        /// <param name="panel">布局面板</param>
        /// <param name="name">文件名称</param>
        public static void Save(this Panel panel, string name)
        {
            var data = GetConfiguration(panel.Children);
            if (!name.ToUpper().EndsWith(".TXT"))
            {
                name += ".TXT";
            }
            string path = Path.Combine(Personal, name);
            string contents = JsonConvert.SerializeObject(data, Formatting.None);
            File.WriteAllText(path, contents);
        }

        /// <summary>
        /// 获取遍历元素内容
        /// </summary>
        /// <param name="Element">元素的有序集合</param>
        /// <returns>返回空间设置信息</returns>
        private static Dictionary<int, object> GetConfiguration(UIElementCollection Element)
        {
            var data = new Dictionary<int, object>();
            for (int i = 0; i < Element.Count; i++)
            {
                var item = Element[i];
                if (GetIsRecord(item))
                {
                    if (item is TextBox text)
                    {
                        data[i] = text.Text;
                    }
                    else if (item is ToggleButton toogle)
                    {
                        data[i] = toogle.IsChecked;
                    }
                }
                if (Extend(item, out var value))
                {
                    data[i] = value;
                }
            }
            if (data.Count == 0)
            {
                data = null;
            }
            return data;
        }

        /// <summary>
        /// 递归 Panel  和判断   ContentControl.Children 是否还有内容
        /// </summary>
        /// <param name="ui"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        private static bool Extend(UIElement ui, out Dictionary<int, object> data)
        {
            data = null;
            if (ui is Panel panel)
            {
                data = GetConfiguration(panel.Children);
            }
            else if (ui is ContentControl content && content.Content is Panel pane)
            {
                data = GetConfiguration(pane.Children);
            }
            return data != null;
        }

        #endregion 保存配置

        #region 读取配置

        /// <summary>
        /// /读取窗口配置
        /// </summary>
        /// <param name="window">控件</param>
        /// <param name="name">文件名称</param>
        public static void Read(this ContentControl window, string name)
        {
            if (window.Content is Panel panel)
            {
                Read(panel, name);
            }
        }

        /// <summary>
        /// /读取窗口配置
        /// </summary>
        /// <param name="panel">布局面板</param>
        /// <param name="name">文件名称</param>
        public static void Read(this Panel panel, string name)
        {
            if (!name.ToUpper().EndsWith(".TXT"))
            {
                name += ".TXT";
            }
            string path = Path.Combine(Personal, name);
            if (File.Exists(path))
            {
                string contents = File.ReadAllText(path);
                if (contents.Length > 0)
                {
                    var data = JsonConvert.DeserializeObject<JObject>(contents);
                    if (data?.Count > 0)
                    {
                        SetConfiguration(panel.Children, data);
                    }
                }
            }
        }

        /// <summary>
        /// 设置空间配置
        /// </summary>
        /// <param name="Element">元素的有序集合</param>
        /// <param name="data">保存配置信息</param>
        private static void SetConfiguration(UIElementCollection Element, JObject data)
        {
            for (int i = 0; i < Element.Count; i++)
            {
                if (data.TryGetValue(i.ToString(), out var value))
                {
                    var item = Element[i];
                    if (item is TextBox text)
                    {
                        text.Text = value.Value<string>();
                    }
                    else if (item is ToggleButton toogle)
                    {
                        toogle.IsChecked = value.Value<bool?>();
                    }
                    else if (value.HasValues)
                    {
                        SetPanel(item, value.Value<JObject>());
                    }
                }
            }
        }

        /// <summary>
        /// 递归 Panel  和判断   ContentControl.Children
        /// </summary>
        /// <param name="ui">控件</param>
        /// <param name="data">配置信息</param>
        private static void SetPanel(UIElement ui, JObject data)
        {
            if (ui is Panel panel)
            {
                SetConfiguration(panel.Children, data);
            }
            else if (ui is ContentControl content && content.Content is Panel pane)
            {
                SetConfiguration(pane.Children, data);
            }
        }

        #endregion 读取配置
    }
}